package com.yubest;

import java.util.ArrayList;
import java.util.List;

/**
 * 给定一个有相同值的二叉搜索树（BST），找出 BST 中的所有众数（出现频率最高的元素）。
 *
 * 假定 BST 有如下定义：
 *
 * 结点左子树中所含结点的值小于等于当前结点的值
 * 结点右子树中所含结点的值大于等于当前结点的值
 * 左子树和右子树都是二叉搜索树
 * 例如：
 * 给定 BST [1,null,2,2],
 *
 *    1
 *     \
 *      2
 *     /
 *    2
 * 返回[2].
 *
 * 提示：如果众数超过1个，不需考虑输出顺序
 *
 * 进阶：你可以不使用额外的空间吗？（假设由递归产生的隐式调用栈的开销不被计算在内）
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/find-mode-in-binary-search-tree
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 *
 * @Author hweiyu
 * @Description
 * @Date 2021/11/10 14:50
 */
public class P0501 {

    public static void main(String[] args) {
        TreeNode root = new TreeNode(1);
        root.right = new TreeNode(2);
        root.right.left = new TreeNode(2);
        new Solution501().findMode(root);
    }
}

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution501 {

    //存储的众数
    private List<Integer> result = new ArrayList<>();

    //当前计算的数
    private Integer cur;

    //当前数出现次数
    private Integer count = 0;

    //数出现的最大次数
    private Integer max = 0;

    /**
     * 思路：二叉搜索树，进行中序遍历时，所形成的数组是一个非递减数组，所以可以转化为在一个非递减数组中找出众数
     * @param root
     * @return
     */
    public int[] findMode(TreeNode root) {
        dfs(root);
        //处理最后一次遍历
        if (count > max) {
            result.clear();
            result.add(cur);
        } else if (count.equals(max)) {
            result.add(cur);
        }
        int[] r = new int[result.size()];
        for (int i = 0; i < result.size(); i++) {
            r[i] = result.get(i);
        }
        return r;
    }

    private void dfs(TreeNode node) {
        if (null == node) {
            return;
        }
        dfs(node.left);
        if (cur == null) {
            cur = node.val;
            count = 1;
        } else if (cur == node.val) {
            count++;
        } else if (count.equals(max)) {
            result.add(cur);
            count = 1;
            cur = node.val;
        } else if (count > max){
            result.clear();
            result.add(cur);
            max = count;
            count = 1;
            cur = node.val;
        } else {
            count = 1;
            cur = node.val;
        }
        dfs(node.right);
    }

}
